package com.guigui.gulimall.ware.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guigui.common.constant.WareConstant;
import com.guigui.common.utils.PageUtils;
import com.guigui.common.utils.Query;
import com.guigui.gulimall.ware.dao.PurchaseDao;
import com.guigui.gulimall.ware.dto.MergeReceiveDto;
import com.guigui.gulimall.ware.dto.PurchaseDoneDto;
import com.guigui.gulimall.ware.dto.PurchaseDoneItemDto;
import com.guigui.gulimall.ware.entity.PurchaseDetailEntity;
import com.guigui.gulimall.ware.entity.PurchaseEntity;
import com.guigui.gulimall.ware.feign.ProductSpuInfoFeignService;
import com.guigui.gulimall.ware.service.PurchaseDetailService;
import com.guigui.gulimall.ware.service.PurchaseService;
import com.guigui.gulimall.ware.service.WareSkuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Autowired
    private PurchaseDetailService purchaseDetailService;

    @Autowired
    private WareSkuService wareSkuService;

    @Autowired
    private ProductSpuInfoFeignService productSpuInfoFeignService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryUnreceiveList(Map<String, Object> params) {
        QueryWrapper<PurchaseEntity> queryWrapper = new QueryWrapper<PurchaseEntity>().eq("status", 0).or().eq("status", 1);
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }

    @Transactional(rollbackFor = Throwable.class)
    @Override
    public void mergeReceive(MergeReceiveDto mergeReceiveDto) {
        List<Long> purchaseDetailIds = mergeReceiveDto.getItems();

        // 过滤掉不能合并的数据
        purchaseDetailIds = purchaseDetailService.listByIds(purchaseDetailIds).stream()
                .filter(item -> item.getStatus() == WareConstant.PurchaseDetailStatus.CREATED.getCode())
                .map(PurchaseDetailEntity::getId)
                .collect(Collectors.toList());

        // 没剩下的就跳出
        if (purchaseDetailIds.size() == 0) return;

        // purchaseId为空时新建采购单，不为空时update采购单
        Long purchaseId = mergeReceiveDto.getPurchaseId();
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setStatus(WareConstant.PurchaseStatus.ASSIGNED.getCode());
        purchaseEntity.setUpdateTime(new Date());

        if (purchaseId == null) {
            purchaseEntity.setCreateTime(new Date());
            this.save(purchaseEntity);
            purchaseId = purchaseEntity.getId();
        } else {
            purchaseEntity.setId(purchaseId);
            this.updateById(purchaseEntity);
        }

        // 提交过来的items转purchase实体对象
        Long finalPurchaseId = purchaseId;
        List<PurchaseDetailEntity> purchaseDetailEntities = purchaseDetailIds.stream().map(id -> {
            PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
            purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailStatus.ASSIGNED.getCode());
            purchaseDetailEntity.setId(id);
            purchaseDetailEntity.setPurchaseId(finalPurchaseId);
            return purchaseDetailEntity;
        }).collect(Collectors.toList());
        purchaseDetailService.updateBatchById(purchaseDetailEntities);

    }

    @Transactional(rollbackFor = Throwable.class)
    @Override
    public void receive(List<Long> purchaseId) {
        purchaseId = purchaseId.stream().distinct().collect(Collectors.toList());

        // 1、更新wms_purchase表中数据的状态
        List<PurchaseEntity> needUpdatePurchaseEntities = purchaseId.stream().map(p -> {
            PurchaseEntity entity = new PurchaseEntity();
            entity.setStatus(WareConstant.PurchaseStatus.RECEIVE.getCode());
            entity.setUpdateTime(new Date());
            entity.setId(p);
            return entity;
        }).collect(Collectors.toList());
        this.updateBatchById(needUpdatePurchaseEntities);

        List<PurchaseDetailEntity> purchaseDetailEntities = purchaseDetailService.list(
                new QueryWrapper<PurchaseDetailEntity>().in("purchase_id", purchaseId)
        );
        if (purchaseDetailEntities.size() == 0) return;
        // 2、跟新wms_purchase_detail表中的数据状态
        // 只有新建和已分配状态才支持领取操做，这一步剔除之外状态的任务
        purchaseDetailEntities = purchaseDetailEntities.stream()
                .filter(p -> p.getStatus() == WareConstant.PurchaseStatus.CREATED.getCode() || p.getStatus() == WareConstant.PurchaseStatus.ASSIGNED.getCode())
                .collect(Collectors.toList());
        if (purchaseDetailEntities.size() == 0) return;

        List<PurchaseDetailEntity> needUpdatePurchaseDetail = purchaseDetailEntities.stream().map(p -> {
            PurchaseDetailEntity detailEntity = new PurchaseDetailEntity();
            detailEntity.setStatus(WareConstant.PurchaseDetailStatus.BUYING.getCode());
            detailEntity.setId(p.getId());
            return detailEntity;
        }).collect(Collectors.toList());
        purchaseDetailService.updateBatchById(needUpdatePurchaseDetail);
    }

    @Transactional(rollbackFor = Throwable.class)
    @Override
    public void purchaseDone(PurchaseDoneDto purchaseDoneDto) {
        // 1.完成采购单
        Long purchaseId = purchaseDoneDto.getId();
        PurchaseEntity willDonePurchase = this.getById(purchaseId);
        if (willDonePurchase == null) return;

        // 1.1、扫描全部采购详情，全部采购成功即修改采购单状态为完成，否则标记为采购异常
        List<PurchaseDoneItemDto> doneItems = purchaseDoneDto.getItems();
        boolean purchaseDoneStatus = true;
        for (PurchaseDoneItemDto item : doneItems) {
            if (item.getStatus() == WareConstant.PurchaseDetailStatus.ERROR.getCode()) {
                purchaseDoneStatus = false;
                break;
            }
        }
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(purchaseId);
        purchaseEntity.setUpdateTime(new Date());
        // 标志位为true表示ok状态
        if (purchaseDoneStatus) purchaseEntity.setStatus(WareConstant.PurchaseStatus.OK.getCode());
        else purchaseEntity.setStatus(WareConstant.PurchaseStatus.ERROR.getCode());
        this.updateById(purchaseEntity);

        // 1.2、状态为BUYING的商品入库 willDonePurchase 表
        List<Long> detailIds = doneItems.stream().map(items -> {
            if (items.getStatus() == WareConstant.PurchaseStatus.OK.getCode()) return items.getItemId();
            else return null;
        }).filter(Objects::nonNull).collect(Collectors.toList());

        // 1.3、完成入库
        List<PurchaseDetailEntity> purchaseDetailEntityList = purchaseDetailService.listByIds(detailIds);
        if (purchaseDetailEntityList.size() > 0) wareSkuService.addWare(purchaseDetailEntityList);

        // 2.修改采购单详情状态
        List<PurchaseDetailEntity> needUpdatePurchaseDetailCollect = doneItems.stream().map(items -> {
            PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
            purchaseDetailEntity.setId(items.getItemId());
            purchaseDetailEntity.setStatus(items.getStatus());

            // TODO 没有失败原因字段
            return purchaseDetailEntity;
        }).collect(Collectors.toList());
        purchaseDetailService.updateBatchById(needUpdatePurchaseDetailCollect);
    }

}